package com.example.demo.service.Impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.Mapper.MenuMapper;
import com.example.demo.Mapper.RoleMapper;
import com.example.demo.Mapper.UserMapper;
import com.example.demo.dto.MenuDto;
import com.example.demo.entity.Menu;
import com.example.demo.entity.Role;
import com.example.demo.entity.User;
import com.example.demo.service.MenuService;
import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yaml.snakeyaml.util.ArrayUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private MenuMapper menuMapper;

    @Override
    public HashMap<Integer, MenuDto> selectMenuByUserId(String userId) {
//        final User user = userMapper.selectById(userId);
//        final Role role = roleMapper.selectById(user.getRole_id());
//        final String menuIdString = role.getMenuId();
        String[] split = "5,6,7,26,27,29".split(",");
        if(userId == "-999") {
            final List<Menu> menus = menuMapper.selectList(null);
            String iui = "";
            for(int osp = 0; osp < menus.size(); osp++) {
                iui += menus.get(osp).getId() + ",";
            }
            split = iui.split(",");
        }
        List<MenuDto> list = new ArrayList<>();
        HashMap<Integer, MenuDto> hashMap = new HashMap<>();

        for(int i = 0; i < split.length; i++) {
            final int i1 = Integer.parseInt(split[i]);
            MenuDto menuDto = new MenuDto();
            final Menu menu = menuMapper.selectById(i1);
            menuDto.setId(menu.getId());
            menuDto.setComponentPath(menu.getComponentPath());
            menuDto.setIocn(menu.getIocn());
            menuDto.setMenuName(menu.getMenuName());
            menuDto.setMenuOrder(menu.getMenuOrder());
            menuDto.setParentId(menu.getParentId());
            menuDto.setRedirect(menu.getRedirect());
            menuDto.setTitle(menu.getTitle());
            menuDto.setChildren(new ArrayList<>());
            menuDto.setPath(menu.getPath());
            hashMap.put(i1, menuDto);
            list.add(menuDto);
        }
        for (int j = 0; j < list.size(); j++) {
            d(list.get(j), hashMap);
        }
        return hashMap;
    }

    @Override
    public int addMenu(Menu menu) {
        if(this.isAgainPath(menu.getPath()) || this.isAgainMenuName(menu.getMenuName())) {
            return  -1;
        }
        final int insert = menuMapper.insert(menu);
        return insert;
    }

    @Override
    public Menu selectMenuOneById(String id) {
        final Menu menu = menuMapper.selectById(id);
        return menu;
    }

    @Override
    public int updateMenu(Menu menu) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", menu.getId());
        final int update = menuMapper.update(menu, queryWrapper);
        return update;
    }

    @Override
    public Object selectAll(String title, String menuName) {
        Object a = "";

        try {
            final Object loginId = StpUtil.getLoginId();
            a = loginId;
        } catch (Exception e) {
            List<Menu> list = new ArrayList<>();
            return list;
        }
        final User user = userMapper.selectById(a.toString());
        final Role role = roleMapper.selectById(user.getRoleId());
        final String[] split = role.getMenuId().split(",");

        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("title", title);
        queryWrapper.like("menu_name", menuName);
        final List<Menu> menus = menuMapper.selectList(queryWrapper);

        List<Menu> spMe = new ArrayList<>();

        for (int j = 0; j < menus.size();j++) {
            for (int l = 0; l < split.length;l++) {
                if((menus.get(j).getId() + "").equals(split[l])) {
                    spMe.add(menus.get(j));
                }
            }
        }
        List<MenuDto> menuDtos = new ArrayList<>();
        for(int i = 0; i < spMe.size();i++) {
            MenuDto menuDto = new MenuDto();
            menuDto.setMenuName(spMe.get(i).getMenuName());
            menuDto.setMenuOrder(spMe.get(i).getMenuOrder());
            menuDto.setPath(spMe.get(i).getPath());
            menuDto.setTitle(spMe.get(i).getTitle());
            menuDto.setRedirect(spMe.get(i).getRedirect());
            menuDto.setIocn(spMe.get(i).getIocn());
            menuDto.setComponentPath(spMe.get(i).getComponentPath());
            menuDto.setId(spMe.get(i).getId());
            menuDto.setParentId(spMe.get(i).getParentId());
            List<MenuDto> menuDtos1 = new ArrayList<>();
            menuDto.setChildren(menuDtos1);

            menuDtos.add(menuDto);
        }

        final Map<String, Object> tree = this.getTree(menuDtos);
        final Collection<Object> values = tree.values();
        final Object[] objects = values.toArray();
        return objects[0];
    }


    public static Map<String, Object> getTree(List<MenuDto> list) {

        Map<String, Object> resmap=new HashMap<>();
        Map<Integer, MenuDto> map;
        List<MenuDto> treelist= new ArrayList<>();
        System.out.println(list);
        if (null==list||list.isEmpty()){
            return null;
        }
        map = list.stream().collect(Collectors.toMap(MenuDto::getId, a -> a,(k1, k2)->k1));
        // 将list集合对象转换为json的字符串
        // 如果id是父级的话就放入tree中treelist
        for (MenuDto menu : list) {
            if (null==map.get(menu.getParentId())) {
                treelist.add(menu);
            } else {
                // 子级通过父id获取到父级的类型
                MenuDto parent = map.get(menu.getParentId());
                // 父级获得子级，再将子级放到对应的父级中
                parent.addChildren(menu);
            }
        }
        resmap.put("data",treelist);
        System.out.println("haha");
        System.out.println(resmap);
        return resmap;
    }


    @Override
    public int delete(String id) {
        final int i = menuMapper.deleteById(id);
        return i;
    }

    @Override
    public Object selectSelect() {

        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        final List<Menu> menus = menuMapper.selectList(queryWrapper);

        List<MenuDto> menuDtos = new ArrayList<>();
        for(int i = 0; i < menus.size();i++) {
            MenuDto menuDto = new MenuDto();
            menuDto.setMenuName(menus.get(i).getMenuName());
            menuDto.setMenuOrder(menus.get(i).getMenuOrder());
            menuDto.setPath(menus.get(i).getPath());
            menuDto.setTitle(menus.get(i).getTitle());
            menuDto.setRedirect(menus.get(i).getRedirect());
            menuDto.setIocn(menus.get(i).getIocn());
            menuDto.setComponentPath(menus.get(i).getComponentPath());
            menuDto.setId(menus.get(i).getId());
            menuDto.setParentId(menus.get(i).getParentId());
            List<MenuDto> menuDtos1 = new ArrayList<>();
            menuDto.setChildren(menuDtos1);

            menuDtos.add(menuDto);
        }

        final Map<String, Object> tree = this.getTree(menuDtos);
        final Collection<Object> values = tree.values();
        final Object[] objects = values.toArray();
        return objects[0];
    }

    Boolean isAgainPath(String path) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("path", path);
        final List<Menu> menus = menuMapper.selectList(queryWrapper);
        return menus.size() > 0;
    }
    Boolean isAgainMenuName(String name) {
        QueryWrapper<Menu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("menu_name", name);
        final List<Menu> menus = menuMapper.selectList(queryWrapper);
        return menus.size() > 0;
    }

    void d(MenuDto menuDto, HashMap<Integer, MenuDto> hashMap) {
        final int parentID = menuDto.getParentId();
        if(parentID == -1) return;

        final MenuDto menuDto1 = hashMap.get(parentID);
        if(menuDto1.getChildren().stream().map(item -> item.getId()).collect(Collectors.toList()).contains(menuDto.getId())) {
            return;
        }
        menuDto1.getChildren().add(menuDto);

        d(menuDto1, hashMap);
    }
}
